Skip to content

feat(geothermal): replace the well dropdown with a search interface - #343

Merged
jirhiker merged 2 commits into
stagingfrom
BDMS-1133
Aug 10, 2026
Merged

feat(geothermal): replace the well dropdown with a search interface#343
jirhiker merged 2 commits into
stagingfrom
BDMS-1133

Conversation

@jirhiker

@jirhiker jirhiker commented Aug 10, 2026

Copy link
Copy Markdown
Member

BDMS-1133. Frontend half; the backend q parameter is DataIntegrationGroup/OcotilloAPI#820.

Why

WellPickerPage — shared by the Records Grid and the Temp-Depth log — was a single dropdown populated by one request for the first 500 wells. The catalogue runs to thousands, so it both hid most of the data with nothing to indicate it had, and made the wells it did show reachable only by scrolling. A well that existed but was not listed looked exactly like a well that did not exist.

What

The picker is now a search box.

  • Term is debounced 300 ms and sent to the server as q, so narrowing happens across the whole catalogue rather than within one loaded page.
  • Each result shows the well's name over a detail line (API, type, status, county, operator) built only from the fields that well actually has, so rows never carry a run of empty separators.
  • Arrow keys move the highlight, Enter opens, Escape clears. Enter with a single result opens it without needing to highlight first. The highlight follows itself into view.
  • A status line reports "Showing N of M wells", so the size of the match set is always visible. Page size grows by 50 via "Show more" up to 500 loaded at once; on reaching that ceiling the line says to narrow the search rather than truncating quietly.

geothermalDataProvider.getList gains meta.params passthrough, mirroring the ocotillo provider, so the term can reach the query string. Null, undefined and empty values are skipped rather than serialised as the literals "null"/"undefined".

Scope

Both pickers, not just Temp-Depth. They are the same component with the same defect, so a shared fix avoids the two pages diverging.

Degradation

If q is not deployed, the parameter is ignored and the endpoint returns its unfiltered first page. The picker still lists and pages wells, but typing narrows nothing — and the "Showing N of M" line makes that visible, because the total will not move as the term changes. The previous design failed silently; this one fails in the open.

Also here: regenerated API types

The committed openapi-auth.json had drifted to 61 paths against the API's current 70. Nothing referenced the missing endpoints, so it was invisible — but it meant src/generated carried no types for them, which is why the geothermal well interface is hand-written and its comment calls the fields "PROVISIONAL … confirm against the backend contract once it lands".

Regenerated against a local API running current staging. Purely additive at the schema level: 9 paths and 7 component schemas gained, none removed, and no endpoint lost a parameter.

/asset/unassociated                     /health
/asset/upload-and-record                /thing/geothermal-well
/asset/{asset_id}/association           /thing/geothermal-well/{well_data_id}
/disclaimer
/feedback
/group/{group_id}/things/{thing_id}

The spec file stays minified, as it was, so its diff is one line rather than sixteen thousand.

A line-level diff of src/generated appears to drop filter?: string from four endpoints and delete the large Organization enum. Neither is real: comparing the two specs endpoint by endpoint, the filter parameter appears on 15 endpoints in both with none lost or gained, and Organization is still emitted. The generator simply places some declarations differently.

This does not change any type the app already used — tsc passes unchanged. It is a separate commit and can be dropped from this PR without touching the feature.

Tests

19 new: label fallback order (name → API → well number → id) including whitespace-only names, detail-line assembly, q omitted when blank, arrow-key wrapping at both ends and on an empty list, unroutable rows dropped, and provider passthrough including the skip-empties case.

tsc clean, no new lint findings, 324 tests pass. The single failure, FieldCompilationNotesPdf.test.ts on DOMMatrix is not defined, is pre-existing — confirmed by stashing these changes and re-running.

Not verified end to end

The search UI is proven at the unit level and the backend q is proven against the seeded dev database, but the two have not been exercised together in a browser: VITE_NMBGMR_GEOTHERMAL_API_URL is unset in every .env example, so settings.tsx falls back to the Ocotillo URL. Worth confirming how staging sets that. Once both are deployed, the check is to type a partial well name and watch the "Showing N of M" total move.

Contract for the parameter: docs/geothermal-well-search-contract.md.

🤖 Generated with Claude Code

The Records Grid and Temp-Depth log both start at WellPickerPage, which was a
single dropdown populated by one request for the first 500 wells. The
catalogue runs to thousands, so that both hid most of the data — with nothing
to indicate it had — and made the wells it did show reachable only by
scrolling. A well that existed but was not listed looked exactly like a well
that did not exist.

The picker is now a search box:

- The term is debounced 300 ms and sent to the server as `q`, so narrowing
  happens across the whole catalogue rather than within one page.
- Results show the well's name over a detail line (API, type, status, county,
  operator) built only from the fields that well actually has.
- Arrow keys move the highlight, Enter opens, Escape clears. Enter with a
  single result opens it without needing to highlight first.
- A status line reports "Showing N of M wells", so the size of the match set
  is always visible. Page size grows by 50 via "Show more" up to 500 loaded at
  once, and on reaching that ceiling the line says to narrow the search rather
  than truncating quietly.

geothermalDataProvider.getList gains `meta.params` passthrough, mirroring the
ocotillo provider, so the search term can reach the query string. Null,
undefined and empty values are skipped rather than serialised as literals.

`q` is not implemented server-side — see the contract in
docs/geothermal-well-search-contract.md. Until it is, the parameter is ignored
and the endpoint returns its unfiltered first page: the picker still lists and
pages wells, but typing narrows nothing, and the "Showing N of M" line makes
that visible instead of hiding it. The previous design failed silently; this
one fails in the open.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Preview Deployment

Preview URL: https://preview-bdms-1133-auejgdbofq-uc.a.run.app

Note: This preview uses the staging API endpoints.

The committed openapi-auth.json had drifted to 61 paths against the API's
current 70. Nothing referenced the missing endpoints, so this was invisible —
but it meant src/generated carried no types for them, and the geothermal well
interface had to be hand-written (src/interfaces/geothermal/IWell.ts, whose
comment calls its fields "PROVISIONAL … confirm against the backend contract
once it lands").

Regenerated against a local API running current staging. Purely additive at the
schema level: 9 paths and 7 component schemas gained, none removed, and no
endpoint lost a parameter.

  /asset/unassociated                     /health
  /asset/upload-and-record                /thing/geothermal-well
  /asset/{asset_id}/association           /thing/geothermal-well/{well_data_id}
  /disclaimer
  /feedback
  /group/{group_id}/things/{thing_id}

The spec file is kept minified, as it was, so its diff stays one line rather
than sixteen thousand.

Typecheck passes unchanged — this adds types without altering any the app
already used.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Preview Deployment

Preview URL: https://preview-bdms-1133-auejgdbofq-uc.a.run.app

Note: This preview uses the staging API endpoints.

@jirhiker
jirhiker merged commit fcbc7d9 into staging Aug 10, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant